from action import *
from facility.window_fn import Window,list_wid_by_pid
from action.setting import *
import time
from facility.input_hook import detect_input
from facility.contro_fn import KeyboardKey,MouseButton
import sys
import multiprocessing
import os
import signal
from facility.ctx.redis_con import redis_connect
from facility.random_fn import random_int
from action.find import check_mask


class Legend(Move,Pannel,Attack):
    stack = list()
    def __init__(self,pid = None, win_id =None):
        assert pid is not None or win_id is not None

        if win_id is not None:
            win = Window.load(win_id)
        else:
            idx = list_wid_by_pid(pid)
            if isinstance(idx,list):
                idx = idx[1]

            win = Window.load(idx)

        super().__init__(win)

        self.process = Process(pid)
        self.state = 'fadai'
        self._state_start = 0
        self.yz = None


        this = os.getpid()

        def hook(key):
            if key == 'q':
                os.kill(this,signal.SIGTERM)
                sys.exit('quit')
            if key == 'a':
                self.tap_key(KeyboardKey.KEY_F12)


        def coordinate_catch():
            with redis_connect() as rd:
                while True:
                    try:
                        res = self.coordinate()
                        rd.set('coordinate',res)
                    except:
                        print('coordinate_catch Process error')


        def loop_check():
            while True:
                time.sleep(5)
                frame = self.window.snap()
                res = check_mask(frame)
                print('\t\t\t\tMASK CHECK:***',res,end='\r')
                if res is not None:
                    Pic.load(frame).save(str(time.time())+".png")
                    print(res)
                    print(type(res))
                    print(type(res[0]))
                    x = self.window.x_offset+int(res[0])
                    y = self.window.y_offset+int(res[1])
                    self.yz = [x,y]
                    self.change_state('yz')




        branch = [
            multiprocessing.Process(name='key_listen',target=detect_input, args=(hook,)),
            multiprocessing.Process(name='coordinate_catch',target=coordinate_catch,),
            multiprocessing.Process(name='MASK CHECK',target=loop_check,),
        ]

        branch[0].start()
        branch[2].start()




    def run(self):
        dic = {
            'fadai':lambda :print('fadai'),
            'gj':self._handle_gj_state,
            'daguai':self._handle_daguai_state,
            'yz':self._handle_yanzheng,
        }

        while True:
            # print('run loop')
            dic[self.state]()
            print('\tstate: ',self.state,'\tkeep_time: ',self.state_keep_time,end='\r')
            # multiprocessing.Process(target=dic[self.state], args=()).start()


    def _handle_yanzheng(self):
        self.move(self.yz[0], self.yz[1], duration=0)
        time.sleep(0.5)
        self.click(MouseButton.LEFT)
        self.change_state('gj')


    def change_state(self,state):
        self.state = state
        self._state_start = time.time()
        self.stack = list()


    def _handle_gj_state(self):



        if self.stack.__len__() == 0:
            where = self.coordinate(GJ_MAP)

            try:
                map_name = where.split(" ")[0]
                start = (int(where.split(" ")[1].split(":")[0]), int(where.split(" ")[1].split(":")[1]))
            except:
                print('\n','load map error')
                self.tap_key(KeyboardKey.KEY_2)
                self.change_state('gj')
                return


            txt_line = open('./assets/{}'.format(map_dict[map_name]['file']), 'r').readlines()

            txt_line = np.array([np.array([j for j in i if j != '\n']) for i in txt_line])
            txt_line = np.reshape(txt_line,newshape=(300,300))
            print(txt_line.shape)



            map_data = np.array([np.array([j for j in i if j != '\n']) for i in
                                 open('./assets/{}'.format(map_dict[map_name]['file']), 'r').readlines()])
            print(map_data.shape)

            gj_point = map_dict[map_name]['gj']

            end = gj_point[0]

            if start == end:
                print('\n','start == end')
                self.tap_key(KeyboardKey.KEY_2)
                self.change_state('gj')
                return

            print("from:", start, 'to:', end)
            ops = self.a_start_goto_seq(start, end, map_data)
            print(123)
            print(123)
            print(123)
            if ops.__len__()<5:
                print('\n','ops too few')
                self.tap_key(KeyboardKey.KEY_2)
                self.change_state('gj')
                return

            self.stack.extend(ops)

        step = self.stack.pop()
        if step is not None:
            targets = self.find_blood_bar()

            if targets.shape[0]:
                if targets.shape[0]<GJ_SAFE_MON:
                    self.change_state('daguai')
                    return
                else:
                    self.tap_key(KeyboardKey.KEY_2)
                    self.change_state('gj')
                    return
            else:
                self.char_move(step)

        if self.state_keep_time > XL_TIME_LIMIT:
            self.tap_key(KeyboardKey.KEY_2)
            self.change_state('gj')



    def _handle_daguai_state(self):
        if self.random_attack():
            self.pick_up()
        else:
            self.change_state('gj')
            return

    @property
    def state_keep_time(self):
        return time.time()-self._state_start



if __name__ == '__main__':
    from facility.args_fn import Args
    from tasks.kb import KB
    import numpy as np
    from Process import Process
    from facility import Pic


    pid = 11441
    game = Legend(pid=pid)


    def tr_find():
        game.find_treasure()
        game.move(game.window.x_offset + 649, game.window.y_offset +442, duration=0)




    def gj():
        game.change_state('gj')
        game.run()


    def pp():
        data = game.window.snap()
        Pic.load(data).save('dd.png')
        # Pic.load(data).display()

    def jiadian():
        game.move(game.window.x_offset+276,game.window.y_offset+125)
        start = time.time()
        while time.time()-start<180:
            game.click(MouseButton.LEFT,duration=0.01)



    (Args()
    .register('s',lambda :game.window.snap())
     .register('p',lambda :game.plug())
    .register('k',lambda :game.random_attack())
    .register('c',lambda :tr_find())
    .register('gj',gj)
    .register('-p',lambda :pp)
    .register('-t',lambda :Pic.load(game.window.snap()).save('pick.png'))
    .register('-jd',jiadian)
     .listen())
